package xml;

import interfaces.ILaberinto;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import laberinto.Bolita;
import laberinto.Bolon;
import laberinto.Casilla;
import laberinto.Laberinto;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class LectorDeLaberintoXML {
	
	public ILaberinto crearLaberinto (String rutaArchivoLaberinto) {
		return crearLaberinto ( rutaArchivoLaberinto,"");
	}
	
	public ILaberinto crearLaberinto (String rutaArchivoLaberinto,String id) {
		
		rutaArchivoLaberinto = xmlUtilidades.completarRuta(rutaArchivoLaberinto);
		rutaArchivoLaberinto = xmlUtilidades.completarNombreDeArchivo(rutaArchivoLaberinto);
		ILaberinto laberinto = new Laberinto(id);
		try {
			
			File laberintoXML = new File(rutaArchivoLaberinto);
			DocumentBuilderFactory fabricaDeDocumento = DocumentBuilderFactory.newInstance();
			DocumentBuilder constructorDeDocumento = fabricaDeDocumento.newDocumentBuilder();
			Document contenidoXML = constructorDeDocumento.parse(laberintoXML);
			contenidoXML.getDocumentElement().normalize();

			Element elementoLaberinto = (Element) contenidoXML.getDocumentElement();
			
			laberinto.cambiarCantidadFilas(Integer.parseInt(elementoLaberinto.getAttribute("alto")));
			laberinto.cambiarCantidadColumnas(Integer.parseInt(elementoLaberinto.getAttribute("ancho")));

			NodeList listadoDeCasillasXML = contenidoXML.getElementsByTagName("nodo");

			crearCasillas(laberinto, listadoDeCasillasXML);
			asociarCasillas(laberinto, listadoDeCasillasXML);
			laberinto.cambiarCasillaInicialPacman(elementoLaberinto.getAttribute("inicioPacman"));
			laberinto.cambiarCasillaInicialFantasmas(elementoLaberinto.getAttribute("inicioFantasmas"));
		} 
		catch (Exception e) {
			System.out.println("Error al leer el archivo " + rutaArchivoLaberinto );
			e.printStackTrace();
		}
			return laberinto;
	}



	private void crearCasillas(ILaberinto laberinto, NodeList listadoDeCasillasXML) {
		for (int numeroDeCasilla = 0; numeroDeCasilla < listadoDeCasillasXML.getLength(); numeroDeCasilla++) {

			Node casillaActualXML = listadoDeCasillasXML.item(numeroDeCasilla);
			if (casillaActualXML.getNodeType() == Node.ELEMENT_NODE) {

				Element eCasillaActual = (Element) casillaActualXML;

				Casilla Casilla = new Casilla(eCasillaActual.getAttribute("id"), eCasillaActual.getAttribute("fila"), eCasillaActual.getAttribute("columna"));
				laberinto.agregarCasilla(Casilla);

			}
		}
	}

	/**
	 * Carga las casillas que se encuentran al rededor de cada casilla
	 * Agrega el contenido correspondiente a cada casilla
	 */
	private void asociarCasillas(ILaberinto laberinto, NodeList listadoDeCasillasXML) {
		for (int numeroDeCasilla = 0; numeroDeCasilla < listadoDeCasillasXML.getLength(); numeroDeCasilla++) {

			Node casillaActualXML = listadoDeCasillasXML.item(numeroDeCasilla);
			if (casillaActualXML.getNodeType() == Node.ELEMENT_NODE) {

				Element eCasillaActual = (Element) casillaActualXML;
				
				Casilla CasillaActual = laberinto.obtenerCasillaPorId(eCasillaActual.getAttribute("id"));
								
				if (eCasillaActual.getAttribute("contiene").equals("bolon")) {
					Bolon bolon = new Bolon(CasillaActual);
					laberinto.agregarBolonALaberinto(bolon);
					laberinto.agregarContenidoDeCasilla(bolon, eCasillaActual.getAttribute("id"));
				}
				
				if (eCasillaActual.getAttribute("contiene").equals("bolita")) {
					Bolita bolita = new Bolita(CasillaActual);
					laberinto.agregarContenidoDeCasilla(bolita, eCasillaActual.getAttribute("id"));
					laberinto.agregarBolitaALaberinto(bolita);
				}

				Casilla CasillaArriba = laberinto.obtenerCasillaPorId(eCasillaActual.getAttribute("arriba"));
				CasillaActual.setearArriba(CasillaArriba);

				Casilla CasillaAbajo = laberinto.obtenerCasillaPorId(eCasillaActual.getAttribute("abajo"));
				CasillaActual.setearAbajo(CasillaAbajo);
				
				Casilla CasillaAIzquierda = laberinto.obtenerCasillaPorId(eCasillaActual.getAttribute("izquierda"));
				CasillaActual.setearIzquierda(CasillaAIzquierda);
			
				Casilla CasillaADerecha = laberinto.obtenerCasillaPorId(eCasillaActual.getAttribute("derecha"));
				CasillaActual.setearDerecha(CasillaADerecha);
			}
		}
	}
}